package ai;

import java.util.List;

public class MiniMax {

    private int smartnessLevel;
    private Problem problem;
    private byte maxPlayer;

    public MiniMax(Problem problem, byte maxPlayer, int smartnessLevel) {
        this.problem = problem;
        this.maxPlayer = maxPlayer;
        this.smartnessLevel = smartnessLevel;
    }

    public float maxValue(Node node, float alpha, float beta) {
        if (node.getLevel() >= smartnessLevel) {
            return node.getState().heuristicValue(maxPlayer);
        }
        List<State> children = node.getState().getChildren();
        if (children != null && children.size() > 0) {
            for (State childrenState : children) {
                float minValue = minValue(new Node(node.getLevel() + 1, childrenState), alpha, beta);
                if (minValue > alpha) {
                    alpha = minValue;
                }
                if (alpha >= beta) {
                    return beta;
                }
            }
            return alpha;
        } else {
            if (node.getState().getPlayer() == maxPlayer) {
                return -1000 + node.getLevel();
            } else {
                return +1000 - node.getLevel();
            }
        }
    }

    public float minValue(Node node, float alpha, float beta) {
        if (node.getLevel() >= smartnessLevel) {
            return node.getState().heuristicValue(maxPlayer);
        }
        List<State> children = node.getState().getChildren();
        if (children != null && children.size() > 0) {
            for (State childrenState : children) {
                float maxValue = maxValue(new Node(node.getLevel() + 1, childrenState), alpha, beta);
                if (maxValue < beta) {
                    beta = maxValue;
                }
                if (beta <= alpha) {
                    return alpha;
                }

            }
            return beta;
        } else {
            if (node.getState().getPlayer() == maxPlayer) {
                return -1000 + node.getLevel();
            } else {
                return +1000 - node.getLevel();
            }
        }
    }
}
